package com.kudian.restful.service;

import com.kudian.common.exception.ApplicationException;
import com.kudian.common.persistence.HibernateDao;
import com.kudian.common.service.BaseService;
import com.kudian.common.utils.DateUtils;
import com.kudian.common.utils.RegUtils;
import com.kudian.common.utils.UUIDGenerator;
import com.kudian.common.utils.security.Digests;
import com.kudian.common.utils.security.Encodes;
import com.kudian.restful.dao.LoginSessionDao;
import com.kudian.restful.dao.SellerDao;
import com.kudian.restful.dao.UsersDao;
import com.kudian.restful.entity.LoginSession;
import com.kudian.restful.entity.Seller;
import com.kudian.restful.entity.Users;
import com.kudian.restful.vo.login.*;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2016/4/14.
 */
@Service
@Transactional(readOnly = true)
public class UsersService extends BaseService<Users, Integer> {

    private static final Logger logger = Logger.getLogger(UsersService.class);

    // 使用固定的salt
    public static final String salt = "3d06a5c14d010804";

    @Autowired
    private UsersDao usersDao;

    @Autowired
    private LoginSessionDao loginSessionDao;

    @Autowired
    private SellerDao sellerDao;

    @Override
    public HibernateDao<Users, Integer> getEntityDao() {
        return usersDao;
    }

    /**
     * 保存注册用户
     * @param users
     * @return 1：保存失败
     *          0：保存成功
     */
    @Transactional(readOnly=false)
    public void saveUsers(Users users) {
        logger.info("保存注册用户!");
        this.usersDao.save(users);
    }

    /**
     * 根据输入的用户名取得user，
     * @param name
     */
    public Users getUser(String name) {
        String hql = "from Users u where u.isValidated=0 and ";
//        if (RegUtils.isEmail(name)) {
//            hql += "u.email = :name";
//        } else
        if (RegUtils.isMobileNO(name)) {
            hql += "u.mobilePhone = :name";
        } else {
            hql += "u.userName = :name";
        }
        Map<String, Object> m = new HashMap<String, Object>();
        m.put("name", name);
        return getEntityDao().findUnique(hql, m);
    }

    /**
     * 校验用户是否注册过
     * @return
     *          0 : 未注册过
     *          1 : 手机号被注册过
     *          2 : 用户名被注册过
     */
    public int checkRegisterUser(String name, String phone) {
        Users u = usersDao.findUnique(Restrictions.or(Restrictions.and(Restrictions.eq("userName", name), Restrictions.eq("isValidated", (short) 0)),
                Restrictions.and(Restrictions.eq("mobilePhone", phone), Restrictions.eq("isValidated", (short) 0))));
        if (u == null) {
            return 0;
        }

        if (phone.equals(u.getMobilePhone())) {
            return 1;
        }
        return 2;
    }

    /**
     * 登录系统
     * @param loginvo 登录信息
     */
    @Transactional(readOnly=false)
    public String login(LoginVO loginvo) throws ApplicationException {
        String hql = "from Users u where u.isValidated=0 and ";
        hql += " u.password= :password and ";
//        if (RegUtils.isEmail(loginvo.getName())) {
//            hql += "u.email = :name ";
//        } else
        if (RegUtils.isMobileNO(loginvo.getName())) {
            hql += "u.mobilePhone = :name ";
        } else {
            hql += "u.userName = :name ";
        }

        Map<String, Object> m = new HashMap<String, Object>();
        m.put("password", encrypt(loginvo.getPassword()));
        m.put("name", loginvo.getName());
        Users user = getEntityDao().findUnique(hql, m);
        if (user == null) {
            throw new ApplicationException(9999, "用户名或密码输入错误!");
        }
        //
        if (!StringUtils.isBlank(loginvo.getSregistrationid())) {
            user.setSRegistrationId(loginvo.getSregistrationid());
            this.usersDao.save(user);

            //
            List<Users> ls = null;
            if (RegUtils.isMobileNO(loginvo.getName())) {
                ls = this.usersDao.find(Restrictions.ne("mobilePhone", loginvo.getName()), Restrictions.eq("SRegistrationId", loginvo.getSregistrationid()));
            } else {
                ls = this.usersDao.find(Restrictions.ne("userName", loginvo.getName()), Restrictions.eq("SRegistrationId", loginvo.getSregistrationid()));
            }
            for (Users u : ls) {
                u.setSRegistrationId("");
                this.usersDao.save(u);
            }
        }

        LoginSession ls = new LoginSession();
        ls.setAccessToken(UUIDGenerator.getUUID());
        ls.setUserId(user.getUserId());

        Timestamp t = new Timestamp(System.currentTimeMillis());
        ls.setLoginTime(t);
        ls.setLastTime(t);

        loginSessionDao.save(ls);
        return ls.getAccessToken();
    }

    /**
     * 登录系统
     * @param vo 快速登录信息
     */
    @Transactional(readOnly=false)
    public String quicklogin(QuickLoginVO vo) {
        String hql = "from Users u where u.isValidated=0 and ";
        hql += " u.mobilePhone = :mobile ";

        Map<String, Object> m = new HashMap<String, Object>();
        m.put("mobile", vo.getMobile());
        Users user = getEntityDao().findUnique(hql, m);

        if (user == null) {
            user = new Users();

            user.setEmail("");
            user.setMobilePhone(vo.getMobile());
            user.setUserName("");

            user.setAlias("");
            user.setSex((short) 0);
            user.setIsValidated((short) 0);
            // 最大消费
            user.setCreditLine(0.0);

            // 设置默认密码
            user.setPassword(encrypt("88888888"));
            user.setUserMoney(0.0);
            user.setFrozenMoney(0.0);

            Timestamp t = new Timestamp(System.currentTimeMillis());
            user.setRegTime(t);
            user.setLastLogin(t);
            user.setLastTime(t);
            user.setLastIp("");
            // 不特殊
            user.setIsSpecial((short) 0);
            // TODO 生成随机数
            user.setSalt("abcdef");

            //
            if (!StringUtils.isBlank(vo.getSregistrationid())) {
                user.setSRegistrationId(vo.getSregistrationid());

                //
                List<Users> ls = this.usersDao.find(Restrictions.ne("mobilePhone", vo.getMobile()), Restrictions.eq("SRegistrationId", vo.getSregistrationid()));

                for (Users u : ls) {
                    u.setSRegistrationId("");
                    this.usersDao.save(u);
                }
            }
            this.usersDao.save(user);
        } else {
            //
            if (!StringUtils.isBlank(vo.getSregistrationid())) {
                user.setSRegistrationId(vo.getSregistrationid());
                this.usersDao.save(user);
            }
        }

        LoginSession ls = new LoginSession();
        ls.setAccessToken(UUIDGenerator.getUUID());
        ls.setUserId(user.getUserId());

        Timestamp t = new Timestamp(System.currentTimeMillis());
        ls.setLoginTime(t);
        ls.setLastTime(t);
        loginSessionDao.save(ls);
        return ls.getAccessToken();
    }

    /**
     * 对密码加密
     * @return
     */
    public String encrypt(String password) {
        return Encodes.encodeHex(Digests.sha1(password.getBytes(), Encodes.decodeHex(salt), 1024));
    }

    public Users getUserInfo(Integer userId) {
        return this.usersDao.get(userId);
    }

    /**
     * 查询此用户是否是商家用户, 且商家已被审核通过
     * @param access_token
     * @return
     *          0: 个人用户
     *          1: 商家用户
     *          -1: 用户信息异常
     */
    public int checkSellerUser(String access_token) {
        LoginSession ls = loginSessionDao.get(access_token);
        if (ls == null) {
            return -1;
        }

        Users u = usersDao.get(ls.getUserId());
        if (u == null) {
            return -1;
        }

        // Seller s = sellerDao.findUnique(Restrictions.eq("userId", u.getUserId()), Restrictions.eq("sellerStatus", (short)2));
        Seller s = sellerDao.findUnique(Restrictions.eq("userId", u.getUserId()));
        // 只要用户关联过商家,就非普通用户
        if (s == null) {
            return 0;
        }
        return 1;
    }

    /**
     * 直接修改密码
     * @param vo
     * @throws ApplicationException
     */
    @Transactional(readOnly = false)
    public void imModifyPwd(ImModifyPwdVO vo) throws ApplicationException {
        Users u = this.usersDao.findUnique(Restrictions.eq("mobilePhone", vo.getMobilePhone()), Restrictions.eq("isValidated", (short) 0));
        if (u == null) {
            throw new ApplicationException(9999, "无此手机注册用户！");
        }
        // 增加加密
        u.setPassword(encrypt(vo.getNewPwd()));
        u.setLastTime(DateUtils.getSysTimestamp());
        this.usersDao.save(u);
    }

    /**
     * 返回用户手机号
     * @param vo
     * @return
     */
    public String checkUsersName(CheckUserNameVO vo) {
        String mobile = "";
        Users u = null;
        if (RegUtils.isMobileNO(vo.getUserName())) {
            u = this.usersDao.findUnique(Restrictions.eq("mobilePhone", vo.getUserName()), Restrictions.eq("isValidated", (short) 0));
        } else {
            u = this.usersDao.findUnique(Restrictions.eq("userName", vo.getUserName()), Restrictions.eq("isValidated", (short) 0));
        }
        if (u != null) {
            mobile = u.getMobilePhone();
        }
        return mobile;
    }

    public Users getInfo(Integer userId) {
        return usersDao.get(userId);
    }
}
